/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package logica;


import fisica.CapaFisica;
import fisica.EvolucionFisica;
import hibernate.objeto.DiagnosticoYTriageInternacion;
import hibernate.objeto.EnfermedadYDiagnosticoAmbulatorio;
import hibernate.objeto.Evolucion;
import hibernate.objeto.ExamenFisico;
import hibernate.objeto.Farmacologico;
import hibernate.objeto.NoFarmacologico;
import hibernate.objeto.TratamientoMedicamentoso;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.Vector;
import presentacion.CapaPresentacion;

/**
 *
 * @author Gonzalo
 */
public class EvolucionLogica extends CapaLogica {

    /**
     * Crea y persiste la evolución de la enfermedad para el paciente.
     *
     * @param datosEvolucionAmbulatorio Los datos correspondientes a la ficha
     * @param enfermedadYDiagnosticoAmbulatorio La enfermedad con su respectivo
     * diagnostico para asociar la evolucion
     * @param evolucion La evolucion que se está agregando/modificando
     * @param idEvolucion El arreglo donde se guardara el id del objeto creado
     * para su poterior recuperación
     * @return true si se agregó/modificó correctamente, false en caso contrario
     */
    public static boolean agregarEvolucionAmbulatorio(Object[] datosEvolucionAmbulatorio,
            EnfermedadYDiagnosticoAmbulatorio enfermedadYDiagnosticoAmbulatorio,
            Evolucion evolucion, int[] idEvolucion) {

        //Si es una modificacion
        if (idEvolucion[0] != -1) {
            //Escribe el log
            backUpModificacion(idEvolucion[0]);
        }
        
        evolucion = crearUObtenerObjetoEvolucion(
                datosEvolucionAmbulatorio, evolucion);

        //Setea los datos pertinentes a ambulatorio
        evolucion.setEnfermedadYDiagnosticoAmbulatorio(
                enfermedadYDiagnosticoAmbulatorio);
        evolucion.setTipoDePracticaEvolucion("ambulatorio");
        evolucion.setDiagnosticoYTriageInternacion(null);

        //Persiste el objeto
        if (CapaFisica.guardarOActualizarObjeto(evolucion)) {
            idEvolucion[0] = evolucion.getIdEvolucion();
            return true;
        } else {
            return false;
        }
    }

    /**
     * Crea y persiste la evolución de la internación para el paciente.
     *
     * @param datosEvolucionInternacion Los datos correspondientes a la ficha
     * @param diagnosticoYTriageInternacion La internacion con su respectivo
     * diagnostico y triage para asociar la evolucion
     * @param evolucion La evolucion que se está agregando/modificando
     * @param idEvolucion El arreglo donde se guardara el id del objeto creado
     * para su poterior recuperación
     * @return true si se agregó/modificó correctamente, false en caso contrario
     */
    public static boolean agregarEvolucionInternacion(Object[] datosEvolucionInternacion,
            DiagnosticoYTriageInternacion diagnosticoYTriageInternacion,
            Evolucion evolucion, int[] idEvolucion) {

        //Si es una modificacion
        if (idEvolucion[0] != -1) {
            //Escribe el log
            backUpModificacion(idEvolucion[0]);
        }
        
        evolucion = crearUObtenerObjetoEvolucion(
                datosEvolucionInternacion, evolucion);

        //Setea los datos pertinentes a internacion
        evolucion.setDiagnosticoYTriageInternacion(
                diagnosticoYTriageInternacion);
        evolucion.setTipoDePracticaEvolucion("internacion");
        evolucion.setEnfermedadYDiagnosticoAmbulatorio(null);

        //Persiste el objeto
        if (CapaFisica.guardarOActualizarObjeto(evolucion)) {
            idEvolucion[0] = evolucion.getIdEvolucion();
            return true;
        } else {
            return false;
        }
    }

    /**
     * Actualiza el examen físico a la evolución.
     *
     * @param examenFisico El objeto ExamenFisico que se asocia a la evolución
     * @param evolucion La evolución a actualizar
     * @return true si se actualizó correctamente, false en caso contrario
     */
    static boolean actualizarExamenFisico(
            ExamenFisico examenFisico, Evolucion evolucion) {
        evolucion.setExamenFisico(examenFisico);

        if (CapaFisica.guardarOActualizarObjeto(evolucion)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Crea un objeto evolución con los datos pasados por parámetro.
     *
     * @param datosEvolucionAmbulatorio Los datos a cargar
     * @param evolucion La evolucion que se está agregando/modificando
     * @return El objeto Evolucion creado
     */
    private static Evolucion crearUObtenerObjetoEvolucion(
            Object[] datosEvolucionAmbulatorio, Evolucion evolucion){

        if (evolucion == null) {
            evolucion = new Evolucion();
        }

        evolucion.setHoraEvolucion(datosEvolucionAmbulatorio[
                EVOLUCION_HORA].toString());

        evolucion.setFechaEvolucion(
                (Date) datosEvolucionAmbulatorio[EVOLUCION_FECHA]);

        evolucion.setDescripcionEvolucion(
                datosEvolucionAmbulatorio[EVOLUCION_DESCRIPCION].toString());

        evolucion.setApellidoProfesionalEvolucion(
                datosEvolucionAmbulatorio[EVOLUCION_APELLIDO_PROFESIONAL].toString());

        evolucion.setNombreProfesionalEvolucion(
                datosEvolucionAmbulatorio[EVOLUCION_NOMBRE_PROFESIONAL].toString());

        return evolucion;
    }

    /**
     * Retorna el vector de Evoluciones pertenecientes a la práctica ambulatorio
     * que un paciente tiene asociadas.
     *
     * @param idPaciente El id del paciente a consultar
     * @return El vector de objetos EvolucionAmbulatorio consultado
     */
    public static Vector<Evolucion> getVectorEvolucionAmbulatorioPorIdPaciente(
            int idPaciente) {
        return EvolucionFisica.getVectorEvolucionAmbulatorioPorIdPaciente(
                idPaciente);
    }

    /**
     * Retorna el vector de Evoluciones pertenecientes a la práctica internación
     * que un paciente tiene asociadas.
     *
     * @param idPaciente El id del paciente a consultar
     * @return El vector de objetos EvolucionAmbulatorio consultado
     */
    public static Vector<Evolucion> getVectorEvolucionInternacionPorIdPaciente(
            int idPaciente) {
        return EvolucionFisica.getVectorEvolucionInternacionPorIdPaciente(
                idPaciente);
    }

    /**
     * Retorna el objeto Evolucion según el id.
     *
     * @param idEvolucion  El id de la evolución
     * @return El objeto Evolucion consultado, null si no existe
     */
    public static Evolucion getEvolucionPorId(int idEvolucion) {
        return EvolucionFisica.getEvolucionPorId(idEvolucion);
    }

    /**
     * Retorna las evoluciones cargada de la enfermedad consultada.
     *
     * @param idEnfermedadYDiagnosticoAmbulatorio El id de la enfermedad
     * @return El vector de objetos Evolucion consultado
     */
    public static Vector<Evolucion> getVectorEvolucionPorIdEnfermedadYDiagnosticoAmbulatorio(
            int idEnfermedadYDiagnosticoAmbulatorio) {
        return EvolucionFisica.getVectorEvolucionPorIdEnfermedadYDiagnosticoAmbulatorio(
                idEnfermedadYDiagnosticoAmbulatorio);
    }

    /**
     * Retorna las evoluciones cargada de la internación consultada.
     *
     * @param idDiagnosticoYTriageInternacion El id del diagnóstico
     * @return El vector de objetos Evolucion consultado
     */
    public static Vector<Evolucion> getVectorEvolucionPorIdDiagnosticoYTriageInternacion(
            int idDiagnosticoYTriageInternacion) {
        return EvolucionFisica.getVectorEvolucionPorIdDiagnosticoYTriageInternacion(
                idDiagnosticoYTriageInternacion);
    }

    /**
     * Retorna el vector de objetos Evolucion filtrando la enfermedad.
     *
     * @param vectorEvolucionAmbulatorio El vector de objetos a filtrar
     * @param enfermedadYDiagnosticoAmbulatorio La enfermedad en cuestión
     * @return El vector de objetos Evolucion consultado, null si no existe
     */
    public static Vector<Evolucion> filtrarVectorEvolucionesPorEnfermedad(
            Vector<Evolucion> vectorEvolucionAmbulatorio,
            EnfermedadYDiagnosticoAmbulatorio enfermedadYDiagnosticoAmbulatorio) {
        Vector<Evolucion> vectorRetorno = new Vector<Evolucion>();

        if (vectorEvolucionAmbulatorio != null) {
            for (int i = 0; i < vectorEvolucionAmbulatorio.size(); i++) {
                if (vectorEvolucionAmbulatorio.get(i).
                        getEnfermedadYDiagnosticoAmbulatorio().
                        getIdEnfermedadYDiagnosticoAmbulatorio() ==
                        enfermedadYDiagnosticoAmbulatorio.
                        getIdEnfermedadYDiagnosticoAmbulatorio()) {
                    vectorRetorno.add(vectorEvolucionAmbulatorio.get(i));
                }
            }
        }

        if (vectorRetorno.size() > 0) {
            return vectorRetorno;
        } else {
            return null;
        }
    }

    /**
     * Retorna el vector de objetos Evolucion filtrando la internacion.
     *
     * @param vectorEvolucionInternacion El vector de objetos a filtrar
     * @param diagnosticoYTriageInternacion La internacion en cuestión
     * @return El vector de objetos Evolucion consultado, null si no existe
     */
    public static Vector<Evolucion> filtrarVectorEvolucionesPorInternacion(
            Vector<Evolucion> vectorEvolucionInternacion,
            DiagnosticoYTriageInternacion diagnosticoYTriageInternacion) {
        Vector<Evolucion> vectorRetorno = new Vector<Evolucion>();

        if (vectorEvolucionInternacion != null) {
            for (int i = 0; i < vectorEvolucionInternacion.size(); i++) {
                if (vectorEvolucionInternacion.get(i).
                        getDiagnosticoYTriageInternacion().
                        getIdDiagnosticoYTriageInternacion() ==
                        diagnosticoYTriageInternacion.
                        getIdDiagnosticoYTriageInternacion()) {
                    vectorRetorno.add(vectorEvolucionInternacion.get(i));
                }
            }
        }

        if (vectorRetorno.size() > 0) {
            return vectorRetorno;
        } else {
            return null;
        }
    }

    /**
     * Dada una evolución verifica si la enfermedad o internación asociada es
     * activa.
     *
     * @param evolucion La evolución a evaluar
     * @return true si es activa, false si es no activa
     */
    public static boolean esEvolucionActiva(Evolucion evolucion) {
        if (evolucion == null) {
            return true;
        } else if (evolucion.getEnfermedadYDiagnosticoAmbulatorio() != null &&
                evolucion.getEnfermedadYDiagnosticoAmbulatorio().
                getEstadoEnfermedadYDiagnosticoAmbulatorio().
                equalsIgnoreCase("Activa")) {
            return true;
        } else if (evolucion.getDiagnosticoYTriageInternacion() != null &&
                evolucion.getDiagnosticoYTriageInternacion().
                getEstadoDiagnosticoYTriageInternacion().
                equalsIgnoreCase("Activa")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Escribe un archivo de texto el cual es una imagen del objeto que se
     * ha modificado y sus objetos asociados, guardando el mismo en la tabla.
     *
     * @param idObjeto El id del objeto a resguardar
     */
    private static void backUpModificacion(int idObjeto) {
        String rutaLogLocal = DIRECTORIO_DE_TRABAJO + "\\" +
                    Evolucion.class.getName() + ".txt";
        //Se recupera el objeto para recupera el archivo
        Evolucion evolucion = EvolucionLogica.getEvolucionPorId(idObjeto);

        File log = CapaLogica.byteArrayToFile(rutaLogLocal,
                evolucion.getArchivoLogEvolucion());

        if (log == null) {
            log = new File(rutaLogLocal);
        }

        //Se manipula el log
        escribirLogEvolucion(evolucion, rutaLogLocal);

        //Se guarda
        byte[] bFile = new byte[(int) log.length()];

        try {
            FileInputStream fileInputStream = new FileInputStream(log);
            //convert file into array of bytes
            fileInputStream.read(bFile);
            fileInputStream.close();
        } catch (Exception exc) {
            System.err.println(exc.getMessage());
        }

        //Setea el adjunto
        evolucion.setArchivoLogEvolucion(bFile);
        eliminarArchivosTemporales();
    }

    /**
     * Escribe el objeto en un archivo.
     *
     * @param evolucion El objeto a resguardar
     * @param log El archivo en donde escribir
     * @return true si se escribio correctamente, false en caso contrario
     */
    public static boolean escribirLogEvolucion(Evolucion evolucion, String rutaLog) {
        try {
            //Evolucion
            String evolucionString = getEvolucionString(evolucion);

            BufferedWriter bw = new BufferedWriter(new FileWriter(rutaLog, true));
            evolucionString += "\n" + SEPARADOR + "\n";
            //Escribe los datos del objeto
            bw.write(evolucionString);

            bw.close();
        } catch (IOException exception) {
            System.err.println(exception.getMessage());
            return false;
        }

        return true;
    }

    /**
     * Retorna todo el objeto Evolucion en string.
     *
     * @param evolucion El objeto a escribir
     */
    public static String getEvolucionString(Evolucion evolucion) {
        String evolucionString =
                "idEvolucion : " +
                evolucion.getIdEvolucion() + "\n" +
                "horaEvolucion : " +
                evolucion.getHoraEvolucion() + "\n" +
                "fechaEvolucion : " +
                evolucion.getFechaEvolucion() + "\n" +
                "apellidoProfesionalEvolucion : " +
                evolucion.getApellidoProfesionalEvolucion() + "\n" +
                "nombreProfesionalEvolucion : " +
                evolucion.getNombreProfesionalEvolucion() + "\n" +
                "tipoDePracticaEvolucion : " +
                evolucion.getTipoDePracticaEvolucion() + "\n" +
                "descripcionEvolucion : " +
                evolucion.getDescripcionEvolucion() + "\n";

        //Examen Fisico
        if (evolucion.getExamenFisico()!= null) {
            evolucionString += ExamenFisicoLogica.getExamenFisicoString(
                            evolucion.getExamenFisico());
        }

        //Tratamiento
        TratamientoMedicamentoso tratamientoMedicamentoso =
                TratamientoMedicamentosoLogica.getTratamientoMedicamentosoPorIdEvolucion(
                evolucion.getIdEvolucion());
        if (tratamientoMedicamentoso != null) {
            Vector<Farmacologico> vectorFarmacologico = FarmacologicoLogica.
                    getVectorFarmacologicoPorIdTratamientoMedicamentoso(
                    tratamientoMedicamentoso.getIdTratamientoMedicamentoso());
            if(vectorFarmacologico != null){
                for (int i = 0; i < vectorFarmacologico.size(); i++) {
                    evolucionString += SEPARADOR;
                    evolucionString += FarmacologicoLogica.getFarmacologicoString(
                                vectorFarmacologico.get(i));
                }
            }

            Vector<NoFarmacologico> vectorNoFarmacologico = NoFarmacologicoLogica.
                    getVectorNoFarmacologicoPorIdTratamientoMedicamentoso(
                    tratamientoMedicamentoso.getIdTratamientoMedicamentoso());
            if(vectorNoFarmacologico != null){
                for (int i = 0; i < vectorNoFarmacologico.size(); i++) {
                    evolucionString += SEPARADOR;
                    evolucionString += NoFarmacologicoLogica.getNoFarmacologicoString(
                                vectorNoFarmacologico.get(i));
                }
            }
        }

        return evolucionString;
    }

    /**
     * Retorna el texto HTML correspondiente a la descripcion de la evolución ya
     * sea ambulatorio o internación.
     *
     * @param evolucion La evolución correspondiente a la práctica ambulatoria
     * o de internación
     * @return El String que contiene el HTML
     */
    public static String getEvolucionHTML(
            Evolucion evolucion) {

        String evolucionHTML = "";

        if (evolucion != null) {
            String examenFisicoHTML = "";
            String epicrisisHTML = "";
            String estado = "";

            if (evolucion.getDiagnosticoYTriageInternacion() != null) {
                estado = evolucion.getDiagnosticoYTriageInternacion().getEstadoDiagnosticoYTriageInternacion();

                if (evolucion.getDiagnosticoYTriageInternacion().getEpicrisisInternacion()
                        != null) {
                    epicrisisHTML += "</font><br><br><hr /><hr /><br>";
                    epicrisisHTML += EpicrisisInternacionLogica.getEpicrisisHTML(
                            evolucion.getDiagnosticoYTriageInternacion().getEpicrisisInternacion());
                }

            } else {
                estado = evolucion.getEnfermedadYDiagnosticoAmbulatorio().getEstadoEnfermedadYDiagnosticoAmbulatorio();
            }

            if (evolucion.getExamenFisico() != null) {
                examenFisicoHTML += "</font><br><br><hr /><hr /><br>";
                examenFisicoHTML += ExamenFisicoLogica.
                        getExamenFisicoHTML(evolucion.getExamenFisico());

            }


            evolucionHTML = "<font size=\"3\" face=\"arial\" color=\"blue\">EVOLUCIÓN</font><br><br> "
                        + "<hr /><font size=\"3\" face=\"arial\" color=\"blue\">Fecha: </font>"
                        + "<font size=\"3\" face=\"arial\">" +
                        CapaPresentacion.imprimirFecha(evolucion.getFechaEvolucion())  + " - " +
                        evolucion.getHoraEvolucion() + "</font><br>"
                        + "<font size=\"3\" face=\"arial\" color=\"blue\">Estado: </font>"
                        + "<font size=\"3\" face=\"arial\">" +
                        estado + "</font><br><hr /><br>"
                        + "<font size=\"3\" face=\"arial\" color=\"blue\">Evolucionó: </font><br>"
                        + "<font size=\"3\" face=\"arial\">" +
                        evolucion.getApellidoProfesionalEvolucion() + ", "
                        + evolucion.getNombreProfesionalEvolucion() + "</font><br><br>"
                        + "<font size=\"3\" face=\"arial\" color=\"blue\">Tipo de práctica de la evolución:</font><br>"
                        + "<font size=\"3\" face=\"arial\">" +
                        capitalizeFirstLetter(evolucion.getTipoDePracticaEvolucion())+ "</font><br><br>"
                        + "<font size=\"3\" face=\"arial\" color=\"blue\">Descripción de la evolución:</font><br>"
                        + "<font size=\"3\" face=\"arial\">" +
                        evolucion.getDescripcionEvolucion().replace("\n", "<br>")
                        + examenFisicoHTML
                        + epicrisisHTML + "</font><br><br>";
        } else {
            evolucionHTML = "<font size=\"3\" face=\"arial\" color=\"blue\">EVOLUCIÓN</font><br><br> " +
                    "<hr /><font size=\"3\" face=\"arial\">No posee</font><br></font><hr />";
        }

        return evolucionHTML;
    }

}
